package com.bluefox.hospital.controller;

import com.bluefox.common.web.dto.result.PageResultDTO;
import com.bluefox.common.web.dto.result.ResultDTO;
import com.bluefox.hospital.convertor.VideoConvertor;
import com.bluefox.hospital.dto.VideoDTO;
import com.bluefox.hospital.model.Video;
import com.bluefox.hospital.repository.VideoRepository;
import com.bluefox.hospital.service.VideoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * Video的管理接口
 *
 * @author
 */
@Slf4j
@RestController
@RequestMapping("/w/videos")
public class VideoController {

    private VideoService videoService;

    private VideoRepository videoRepository;

    private VideoConvertor videoConvertor;

    public VideoController(VideoService videoService, VideoRepository videoRepository, VideoConvertor videoConvertor) {
        this.videoService = videoService;
        this.videoRepository = videoRepository;
        this.videoConvertor = videoConvertor;
    }

    /**
     * 获取分页数据
     *
     * @param pageable 分页+排序参数
     * @return 分页数据
     */
    @RequestMapping(value = "/s", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    public PageResultDTO<VideoDTO> search(final Pageable pageable) {
        final Page<Video> models = this.videoRepository.findAll(pageable);
        return this.videoConvertor.toResultDTO(models);
    }

    /**
     * 取得详细数据
     *
     * @param id 资源ID
     * @return 资源详细
     */

    @RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResultDTO<VideoDTO> get(@PathVariable final Long id) {
        final Video model = this.videoService.get(id);
        return this.videoConvertor.toResultDTO(model);
    }

    /**
     * 新建操作
     *
     * @param videoDTO 新建资源的DTO
     * @return 新建资源
     */

    @RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResultDTO<VideoDTO> create(@RequestBody @Valid final VideoDTO videoDTO) {
        final Video model = this.videoConvertor.toModel(videoDTO);
        this.videoService.create(model);
        if (log.isInfoEnabled()) {
            log.info("{} instance {} was created.", Video.class.getSimpleName(), model.getId());
        }
        return this.videoConvertor.toResultDTO(model);
    }

    /**
     * 更新操作
     *
     * @param id       更新资源的ID
     * @param videoDTO 更新资源的DTO
     * @return 更新后资源
     */

    @RequestMapping(value = "/{id}", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResultDTO<VideoDTO> update(@PathVariable final Long id, @RequestBody @Valid final VideoDTO videoDTO) {
        videoDTO.setId(id);
        final Video model = this.videoConvertor.toModel(videoDTO);
        this.videoService.update(model);
        if (log.isInfoEnabled()) {
            log.info("{} instance {} was updated.", Video.class.getSimpleName(), model.getId());
        }
        return this.videoConvertor.toResultDTO(model);
    }

    /**
     * 删除操作
     *
     * @param Id 资源ID
     * @return 操作结果
     */

    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResultDTO<Void> delete(@PathVariable final Long id) {
        this.videoService.delete(id);
        if (log.isInfoEnabled()) {
            log.info("{} instance {} was deleted.", Video.class.getSimpleName(), id);
        }
        return ResultDTO.success();
    }

    /**
     * 上传视频保存到本地
     *
     * @param file
     * @return
     * @throws IllegalStateException
     */
    @RequestMapping(value = "uploadVideo", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, String> savaVideo(@RequestParam("file") MultipartFile file)
            throws IllegalStateException {
        Map<String, String> resultMap = new HashMap<>();
        try {
            //获取文件后缀
            String fileExt = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1)
                    .toLowerCase();
            // 重构文件名称
            String pikId = UUID.randomUUID().toString().replaceAll("-", "");
            String newVidoeName = pikId + "." + fileExt;
            //保存视频
            File fileSave = new File("D:\\upload\\video", newVidoeName);
            if (!fileSave.exists()) {
                fileSave.mkdirs();
            }
            file.transferTo(fileSave);
            resultMap.put("status", "success");
            resultMap.put("url", newVidoeName);

            return resultMap;

        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("status", "failure");
            return resultMap;

        }
    }

    /**
     * 根据本地视频全路径，响应给浏览器1个视频
     */
    @RequestMapping("/showVideo")
    public void showVideo(HttpServletResponse response, @RequestParam("fileName") String fileName) {
        show(response, fileName, "video");
    }

    /**
     * 响应文件
     *
     * @param response
     * @param fileName 文件全路径
     * @param type     响应流类型
     */
    private void show(HttpServletResponse response, String fileName, String type) {
        try {
            // 以byte流的方式打开文件
            FileInputStream fis = new FileInputStream("D:\\upload\\video\\" + fileName);
            //得到文件大小
            int i = fis.available();
            byte data[] = new byte[i];
            //读数据
            fis.read(data);
            //设置返回的文件类型
            response.setContentType(type + "/*");
            //得到向客户端输出二进制数据的对象
            OutputStream toClient = response.getOutputStream();
            //输出数据
            toClient.write(data);
            toClient.flush();
            toClient.close();
            fis.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("文件不存在");
        }
    }


}
